"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.callLocalService = callLocalService;
exports.clearLocalData = clearLocalData;
const appConfig_1 = require("../config/appConfig");
const STORAGE_KEY = appConfig_1.appConfig.localStorageKey;
const USER_KEY = appConfig_1.appConfig.localUserKey;
const DB_FILE_PATH = `${wx.env.USER_DATA_PATH}/${STORAGE_KEY}.json`;
const LEGACY_COVER_URLS = {
    "https://img01.yzcdn.cn/vant/cake.png": "/assets/images/rice.png",
    "https://img01.yzcdn.cn/vant/muffin.png": "/assets/images/muffin.png",
};
function getFs() {
    return typeof wx.getFileSystemManager === "function" ? wx.getFileSystemManager() : null;
}
function readDBFromFile() {
    const fs = getFs();
    if (!fs)
        return null;
    try {
        const content = fs.readFileSync(DB_FILE_PATH, "utf-8");
        const parsed = JSON.parse(content);
        if (Array.isArray(parsed === null || parsed === void 0 ? void 0 : parsed.users)) {
            return parsed;
        }
    }
    catch (error) {
        // ignore
    }
    return null;
}
function writeDBToFile(db) {
    const fs = getFs();
    if (!fs)
        return;
    try {
        fs.writeFileSync(DB_FILE_PATH, JSON.stringify(db), "utf-8");
    }
    catch (error) {
        console.warn("写入本地文件失败", error);
    }
}
function generateId(prefix) {
    return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
}
function createDefaultDB() {
    const chefOpenId = generateId("user");
    const dinerOpenId = generateId("user");
    const users = [
        {
            _id: generateId("user"),
            _openid: chefOpenId,
            account: "chef",
            nickname: "心动大厨",
            avatarUrl: "https://img01.yzcdn.cn/vant/cat.jpeg",
            role: "chef",
            createdAt: new Date().toISOString(),
            password: "chef123",
        },
        {
            _id: generateId("user"),
            _openid: dinerOpenId,
            account: "diner",
            nickname: "宠爱食客",
            avatarUrl: "https://img.yzcdn.cn/vant/logo.png",
            role: "diner",
            createdAt: new Date().toISOString(),
            password: "diner123",
        },
    ];
    const categories = [
        { key: "stirfry", name: "炒菜", color: "#FF9A9E", icon: "🍲" },
        { key: "rice", name: "米饭", color: "#FBC2EB", icon: "🍚" },
        { key: "fruit", name: "水果", color: "#8EC5FC", icon: "🍉" },
        { key: "whole", name: "粗粮", color: "#A1FFCE", icon: "🥖" },
        { key: "snack", name: "零食", color: "#FAD0C4", icon: "🍪" },
    ];
    const menu = [
        {
            _id: generateId("menu"),
            chefOpenId,
            categoryKey: "stirfry",
            name: "花椒嫩牛",
            description: "带一点麻有一点甜，吃完像被拥抱",
            coverUrl: "https://img01.yzcdn.cn/vant/leaf.jpg",
            stock: 6,
            funValue: 5,
            isActive: true,
            createdAt: new Date().toISOString(),
        },
        {
            _id: generateId("menu"),
            chefOpenId,
            categoryKey: "rice",
            name: "云朵米饭",
            description: "撒上芝士雪花的软糯白米",
            coverUrl: "/assets/images/rice.png",
            stock: 8,
            funValue: 3,
            isActive: true,
            createdAt: new Date().toISOString(),
        },
        {
            _id: generateId("menu"),
            chefOpenId,
            categoryKey: "fruit",
            name: "彩虹果盘",
            description: "五种颜色的当季水果拼盘",
            coverUrl: "https://img01.yzcdn.cn/vant/apple-1.jpg",
            stock: 4,
            funValue: 4,
            isActive: true,
            createdAt: new Date().toISOString(),
        },
        {
            _id: generateId("menu"),
            chefOpenId,
            categoryKey: "whole",
            name: "小麦暖吐司",
            description: "烤得刚好，上桌自带温度",
            coverUrl: "/assets/images/muffin.png",
            stock: 5,
            funValue: 2,
            isActive: true,
            createdAt: new Date().toISOString(),
        },
        {
            _id: generateId("menu"),
            chefOpenId,
            categoryKey: "snack",
            name: "甜心能量球",
            description: "可可与坚果结合的手作小点",
            coverUrl: "https://img.yzcdn.cn/vant/logo.png",
            stock: 10,
            funValue: 6,
            isActive: true,
            createdAt: new Date().toISOString(),
        },
    ];
    return {
        users,
        categories,
        menu,
        orders: [],
    };
}
function ensureDB() {
    let db = readDBFromFile();
    if (!db || !Array.isArray(db.users) || !db.users.length) {
        db = wx.getStorageSync(STORAGE_KEY);
    }
    if (!db || !Array.isArray(db.users) || !db.users.length) {
        db = createDefaultDB();
        wx.setStorageSync(STORAGE_KEY, db);
        writeDBToFile(db);
    }
    migrateLegacyAssets(db);
    return db;
}
function saveDB(db) {
    wx.setStorageSync(STORAGE_KEY, db);
    writeDBToFile(db);
}
function migrateLegacyAssets(db) {
    let updated = false;
    db.menu.forEach((item) => {
        const mapped = LEGACY_COVER_URLS[item.coverUrl];
        if (mapped && mapped !== item.coverUrl) {
            item.coverUrl = mapped;
            updated = true;
        }
    });
    if (updated) {
        saveDB(db);
    }
}
function getActiveUser(db) {
    const openId = wx.getStorageSync(USER_KEY);
    if (!openId)
        return null;
    return db.users.find((user) => user._openid === openId) || null;
}
function setActiveUser(user) {
    if (!user) {
        wx.removeStorageSync(USER_KEY);
    }
    else {
        wx.setStorageSync(USER_KEY, user._openid);
    }
}
function sanitizeUser(user) {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { password } = user, rest = __rest(user, ["password"]);
    return rest;
}
function cloneMenuItem(item) {
    return Object.assign({}, item);
}
function sanitizeOrder(order) {
    return Object.assign(Object.assign({}, order), { items: order.items.map((item) => (Object.assign({}, item))), review: order.review ? Object.assign({}, order.review) : undefined });
}
function requireUser(db) {
    const user = getActiveUser(db);
    if (!user) {
        throw new Error("请先登录");
    }
    return user;
}
function requireChef(db) {
    const user = requireUser(db);
    if (user.role !== "chef") {
        throw new Error("请使用厨师账号");
    }
    return user;
}
function requireDiner(db) {
    const user = requireUser(db);
    if (user.role !== "diner") {
        throw new Error("请使用点餐账号");
    }
    return user;
}
function filterOrdersForUser(db, user, status) {
    if (!user)
        return [];
    const list = db.orders.filter((order) => {
        if (user.role === "chef") {
            return order.chefOpenId === user._openid;
        }
        return order.dinerOpenId === user._openid;
    });
    const filtered = typeof status === "string" ? list.filter((item) => item.status === status) : list;
    return filtered.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
}
function bootstrap() {
    const db = ensureDB();
    const user = getActiveUser(db);
    return {
        envId: "local",
        userProfile: user ? sanitizeUser(user) : null,
        categories: db.categories.map((item) => (Object.assign({}, item))),
        menu: db.menu.map(cloneMenuItem),
        orders: filterOrdersForUser(db, user).map(sanitizeOrder),
    };
}
function listMenu() {
    const db = ensureDB();
    return {
        menu: db.menu.map(cloneMenuItem),
    };
}
function createMenu(payload) {
    var _a, _b, _c;
    const db = ensureDB();
    const chef = requireChef(db);
    const name = (payload.name || "").trim();
    if (!name) {
        throw new Error("请填写菜品名称");
    }
    const categoryKey = (payload.categoryKey || "").trim();
    if (!categoryKey) {
        throw new Error("请选择菜品分类");
    }
    const coverUrl = (payload.coverUrl || "").trim();
    if (!coverUrl) {
        throw new Error("请上传菜品图片");
    }
    const description = (payload.description || "").trim();
    const stockValue = Number((_a = payload.stock) !== null && _a !== void 0 ? _a : 0);
    const funValueRaw = Number((_b = payload.funValue) !== null && _b !== void 0 ? _b : 0);
    const stock = Number.isFinite(stockValue) ? Math.max(0, Math.floor(stockValue)) : 0;
    const funValue = Number.isFinite(funValueRaw) ? Math.max(0, Math.floor(funValueRaw)) : 0;
    const now = new Date().toISOString();
    const menuItem = {
        _id: generateId("menu"),
        chefOpenId: chef._openid,
        categoryKey,
        name,
        description,
        coverUrl,
        stock,
        funValue,
        isActive: (_c = payload.isActive) !== null && _c !== void 0 ? _c : true,
        createdAt: now,
    };
    db.menu.unshift(menuItem);
    saveDB(db);
    return { menu: cloneMenuItem(menuItem) };
}
function updateMenu(payload) {
    const db = ensureDB();
    const chef = requireChef(db);
    if (!payload._id) {
        throw new Error("当前版本仅支持修改菜品");
    }
    const target = db.menu.find((item) => item._id === payload._id && item.chefOpenId === chef._openid);
    if (!target) {
        throw new Error("未找到菜品");
    }
    if (typeof payload.name === "string" && payload.name.trim()) {
        target.name = payload.name.trim();
    }
    if (typeof payload.categoryKey === "string" && payload.categoryKey) {
        target.categoryKey = payload.categoryKey;
    }
    if (typeof payload.description === "string") {
        target.description = payload.description.trim();
    }
    if (typeof payload.coverUrl === "string" && payload.coverUrl.trim()) {
        target.coverUrl = payload.coverUrl.trim();
    }
    if (typeof payload.stock === "number" && !Number.isNaN(payload.stock)) {
        target.stock = Math.max(0, Math.floor(payload.stock));
    }
    if (typeof payload.funValue === "number" && !Number.isNaN(payload.funValue)) {
        target.funValue = Math.max(0, Math.floor(payload.funValue));
    }
    saveDB(db);
    return { menu: Object.assign({}, target) };
}
function removeMenu(payload) {
    const db = ensureDB();
    const chef = requireChef(db);
    const menuId = (payload.menuId || "").trim();
    if (!menuId) {
        throw new Error("缺少菜品 ID");
    }
    const index = db.menu.findIndex((item) => item._id === menuId && item.chefOpenId === chef._openid);
    if (index < 0) {
        throw new Error("未找到菜品");
    }
    db.menu.splice(index, 1);
    saveDB(db);
    return { menuId };
}
function toggleMenuStatusLocal(menuId, isActive) {
    const db = ensureDB();
    const chef = requireChef(db);
    const target = db.menu.find((item) => item._id === menuId && item.chefOpenId === chef._openid);
    if (!target) {
        throw new Error("未找到菜品");
    }
    target.isActive = isActive;
    saveDB(db);
    return { menu: Object.assign({}, target) };
}
function listOrders(params) {
    const db = ensureDB();
    const user = requireUser(db);
    if (params.role === "chef" && user.role !== "chef") {
        throw new Error("请使用厨师账号");
    }
    if (params.role === "diner" && user.role !== "diner") {
        throw new Error("请使用点餐账号");
    }
    const orders = filterOrdersForUser(db, user, params.status);
    return { orders: orders.map(sanitizeOrder) };
}
function submitOrder(payload) {
    const db = ensureDB();
    const diner = requireDiner(db);
    const aggregated = new Map();
    const items = Array.isArray(payload.items) ? payload.items : [];
    for (const item of items) {
        const menuId = item.menuId;
        const quantity = Number(item.quantity || 0);
        if (!menuId || !quantity || quantity <= 0 || Number.isNaN(quantity)) {
            continue;
        }
        const prev = aggregated.get(menuId) || 0;
        aggregated.set(menuId, prev + Math.floor(quantity));
    }
    if (aggregated.size === 0) {
        throw new Error("请选择菜品");
    }
    const orderItems = [];
    let chefOpenId = "";
    for (const [menuId, quantity] of aggregated.entries()) {
        const menuItem = ensureMenuItem(db, menuId);
        if (!chefOpenId) {
            chefOpenId = menuItem.chefOpenId;
        }
        if (menuItem.chefOpenId !== chefOpenId) {
            throw new Error("一次只能向同一位厨师下单");
        }
        if (menuItem.stock < quantity) {
            throw new Error(`${menuItem.name} 库存只剩 ${menuItem.stock} 份啦`);
        }
    }
    for (const [menuId, quantity] of aggregated.entries()) {
        const menuItem = ensureMenuItem(db, menuId);
        menuItem.stock -= quantity;
        orderItems.push({
            menuId,
            name: menuItem.name,
            quantity,
            funValue: menuItem.funValue,
        });
    }
    const note = typeof payload.note === "string" ? payload.note.trim() : "";
    const order = {
        _id: generateId("order"),
        chefOpenId,
        dinerOpenId: diner._openid,
        dinerNickname: diner.nickname,
        note: note || undefined,
        status: "pending",
        items: orderItems,
        createdAt: new Date().toISOString(),
        rejectReason: undefined,
        acceptedAt: undefined,
        startedAt: undefined,
        finishedAt: undefined,
        rejectedAt: undefined,
        closedAt: undefined,
    };
    db.orders.unshift(order);
    saveDB(db);
    return { order: sanitizeOrder(order) };
}
function acceptOrderLocal(orderId) {
    const db = ensureDB();
    const chef = requireChef(db);
    const order = ensureOrder(db, orderId);
    if (order.chefOpenId !== chef._openid) {
        throw new Error("只能操作自己的订单");
    }
    if (order.status !== "pending") {
        throw new Error("当前状态无法接单");
    }
    order.status = "accepted";
    order.acceptedAt = new Date().toISOString();
    order.rejectReason = undefined;
    order.rejectedAt = undefined;
    order.closedAt = undefined;
    saveDB(db);
    return { order: sanitizeOrder(order) };
}
function rejectOrderLocal(orderId, reason) {
    const db = ensureDB();
    const chef = requireChef(db);
    const order = ensureOrder(db, orderId);
    if (order.chefOpenId !== chef._openid) {
        throw new Error("只能操作自己的订单");
    }
    if (order.status !== "pending") {
        throw new Error("当前状态无法拒绝");
    }
    const rejectReason = (reason || "").trim();
    if (!rejectReason) {
        throw new Error("请填写拒绝原因");
    }
    order.status = "rejected";
    order.rejectReason = rejectReason;
    order.rejectedAt = new Date().toISOString();
    order.closedAt = order.rejectedAt;
    order.startedAt = undefined;
    order.finishedAt = undefined;
    order.acceptedAt = undefined;
    order.items.forEach((item) => {
        const menuItem = ensureMenuItem(db, item.menuId);
        if (menuItem.chefOpenId === chef._openid) {
            menuItem.stock += item.quantity;
        }
    });
    saveDB(db);
    return { order: sanitizeOrder(order) };
}
function startCooking(orderId) {
    const db = ensureDB();
    const chef = requireChef(db);
    const order = ensureOrder(db, orderId);
    if (order.chefOpenId !== chef._openid) {
        throw new Error("只能操作自己的订单");
    }
    if (order.status !== "accepted") {
        throw new Error("请先接单");
    }
    order.status = "cooking";
    order.startedAt = new Date().toISOString();
    saveDB(db);
    return { order: sanitizeOrder(order) };
}
function completeCooking(orderId) {
    const db = ensureDB();
    const chef = requireChef(db);
    const order = ensureOrder(db, orderId);
    if (order.chefOpenId !== chef._openid) {
        throw new Error("只能操作自己的订单");
    }
    if (order.status !== "cooking") {
        throw new Error("请先开始制作");
    }
    order.status = "completed";
    order.finishedAt = new Date().toISOString();
    order.closedAt = order.finishedAt;
    saveDB(db);
    return { order: sanitizeOrder(order) };
}
function getOrderDetail(orderId) {
    const db = ensureDB();
    const user = requireUser(db);
    const order = ensureOrder(db, orderId);
    if (user.role === "chef" && order.chefOpenId !== user._openid) {
        throw new Error("只能查看自己的订单");
    }
    if (user.role === "diner" && order.dinerOpenId !== user._openid) {
        throw new Error("只能查看自己的订单");
    }
    return { order: sanitizeOrder(order) };
}
function reviewOrder(payload) {
    const db = ensureDB();
    const diner = requireDiner(db);
    const order = ensureOrder(db, payload.orderId);
    if (order.dinerOpenId !== diner._openid) {
        throw new Error("无法评价别人的订单");
    }
    if (order.status !== "completed") {
        throw new Error("请等厨师完成后再评价");
    }
    const rating = Math.min(5, Math.max(1, Number(payload.rating || 0)));
    if (!rating || Number.isNaN(rating)) {
        throw new Error("请给出星级评分");
    }
    order.review = {
        rating,
        comment: typeof payload.comment === "string" ? payload.comment.trim() : "",
        createdAt: new Date().toISOString(),
    };
    saveDB(db);
    return { order: sanitizeOrder(order) };
}
function registerUser(params) {
    const { account, password, nickname, role } = params;
    if (!account || !password || !nickname) {
        throw new Error("请填写完整信息");
    }
    const db = ensureDB();
    if (db.users.some((user) => user.account === account)) {
        throw new Error("账号已存在");
    }
    if (role !== "chef" && role !== "diner") {
        throw new Error("角色不正确");
    }
    const openId = generateId("user");
    const user = {
        _id: generateId("user"),
        _openid: openId,
        account,
        nickname,
        avatarUrl: role === "chef" ? "https://img01.yzcdn.cn/vant/cat.jpeg" : "https://img.yzcdn.cn/vant/logo.png",
        role,
        createdAt: new Date().toISOString(),
        password,
    };
    db.users.push(user);
    saveDB(db);
    setActiveUser(user);
    return { user: sanitizeUser(user) };
}
function loginUser(params) {
    const { account, password } = params;
    const db = ensureDB();
    const user = db.users.find((item) => item.account === account && item.password === password);
    if (!user) {
        throw new Error("账号或密码错误");
    }
    setActiveUser(user);
    saveDB(db);
    return { user: sanitizeUser(user) };
}
function logoutUser() {
    setActiveUser(null);
    return {};
}
function updateProfile(payload) {
    const db = ensureDB();
    const user = requireUser(db);
    if (payload.nickname && payload.nickname.trim()) {
        user.nickname = payload.nickname.trim();
    }
    if (payload.avatarUrl && payload.avatarUrl.trim()) {
        user.avatarUrl = payload.avatarUrl.trim();
    }
    saveDB(db);
    return { user: sanitizeUser(user) };
}
function ensureMenuItem(db, menuId) {
    const menuItem = db.menu.find((item) => item._id === menuId);
    if (!menuItem) {
        throw new Error("菜品不存在或已下架");
    }
    return menuItem;
}
function ensureOrder(db, orderId) {
    const order = db.orders.find((item) => item._id === orderId);
    if (!order) {
        throw new Error("订单不存在");
    }
    return order;
}
function callLocalService(action, payload = {}) {
    switch (action) {
        case "bootstrap":
            return bootstrap();
        case "authRegister":
            return registerUser(payload);
        case "authLogin":
            return loginUser(payload);
        case "authLogout":
            return logoutUser();
        case "profileUpdate":
            return updateProfile(payload);
        case "menuList":
            return listMenu();
        case "menuCreate":
            return createMenu(payload);
        case "menuUpdate":
            return updateMenu(payload);
        case "menuRemove":
            return removeMenu(payload);
        case "menuToggle":
            return toggleMenuStatusLocal(payload.menuId, payload.isActive);
        case "ordersList":
            return listOrders(payload);
        case "ordersSubmit":
            return submitOrder(payload);
        case "ordersAccept":
            return acceptOrderLocal(payload.orderId);
        case "ordersReject":
            return rejectOrderLocal(payload.orderId, payload.reason);
        case "ordersStart":
            return startCooking(payload.orderId);
        case "ordersComplete":
            return completeCooking(payload.orderId);
        case "ordersDetail":
            return getOrderDetail(payload.orderId);
        case "ordersReview":
            return reviewOrder(payload);
        default:
            throw new Error(`未实现的本地服务: ${action}`);
    }
}
function clearLocalData() {
    wx.removeStorageSync(STORAGE_KEY);
    wx.removeStorageSync(USER_KEY);
    const fs = getFs();
    if (fs) {
        try {
            fs.unlinkSync(DB_FILE_PATH);
        }
        catch (error) {
            // ignore
        }
    }
}
